home *** CD-ROM | disk | FTP | other *** search
/ CICA 1993 April / CICA MS Windows - April 1993.iso / unzipped / util / mews11 / dolock.c < prev    next >
C/C++ Source or Header  |  1992-06-24  |  9KB  |  434 lines

  1. /*    DOLOCK.C:    Machine specific code for File Locking
  2.             for MicroEMACS
  3.             (C)Copyright 1987 by Daniel M Lawrence
  4. */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "eproto.h"
  9. #include    "elang.h"
  10.  
  11. #if    WMCS
  12. /*    file locking for WMCS */
  13.  
  14. #include "sys$disk/sysincl.sys/sysequ.h"
  15. #include <stdio.h>
  16. #include <ctype.h>
  17.  
  18. char msg[] = TEXT35;
  19. /*           "another user" */
  20.  
  21. char *dolock(fname)
  22. char *fname;
  23. {
  24.     int lun,status;
  25.     status = _open(fname,OPREADACC|OPWRITEACC|OPWRITELOCK,-1,&lun);
  26.     if(status == 133 || status == 0 ) return(NULL);
  27.     return(msg);
  28. }
  29.  
  30. char *undolock(fname)
  31. char *fname;
  32. {
  33.     int i,j,k,lun,status;
  34.     char xname[95],c;
  35.     
  36.     for(lun=4; _getfnam(lun,xname) == 0; lun++) {
  37.         for(i=0;i<strlen(xname);i++)    {
  38.             k = i;
  39.             for(j=0;j<strlen(fname);j++)  {
  40.                 c = fname[j];
  41.                 if(islower(c)) c = toupper(c);
  42.                 if(c == xname[k]) { ++k; continue; }
  43.                 if(c == '\0') break;
  44.                 break;
  45.                 }
  46.             if(j == strlen(fname)) {
  47.                 _close(lun,0);
  48.                 return(NULL);
  49.                 }
  50.             }
  51.     }
  52.     return(NULL);
  53. }
  54. #endif
  55.  
  56. #if    FILOCK && (MSDOS || WINNT || OS2 || SUN || USG || V7 || BSD)
  57. #if    OS2 || ((MSDOS || WINNT) && MSC)
  58. #include    <sys/types.h>
  59. #endif
  60. #include    <sys/stat.h>
  61. #include    <errno.h>
  62. #if    MSDOS && TURBO
  63. #include    <dir.h>
  64. #endif
  65. #if    SUN
  66. #include    <sys/dir.h>
  67. #include    <signal.h>
  68. #endif
  69.  
  70. #if    OS2 == 0
  71. #if    ZTC
  72. extern volatile int errno;
  73. #else
  74. #if    MSC == 0
  75. extern int errno;
  76. #endif
  77. #endif
  78. #endif
  79.  
  80. #define LOCKDIR "_xlk"
  81. #define LOCKMSG "LOCK ERROR -- "
  82. #define    LOCKDEBUG    FALSE
  83.  
  84. /*    dolock:    Generic non-UNIX file locking mechinism    */
  85.  
  86. /**********************
  87.  *
  88.  * dolock -- lock the file fname
  89.  *
  90.  * if successful, returns NULL 
  91.  * if file locked, returns username of person locking the file
  92.  * if other error, returns "LOCK ERROR: explanation"
  93.  *
  94.  *********************/
  95.  
  96. char *parse_name(filespec)        /* get name component of filespec */
  97.  
  98. char *filespec;
  99.  
  100. {
  101.     char *rname;
  102.  
  103.     rname = &filespec[strlen(filespec) - 1];
  104.     while (rname >= filespec) {
  105.         if (*rname == DIRSEPCHAR || *rname == DRIVESEPCHAR) {
  106.             ++rname;
  107.             break;
  108.         }
  109.         --rname;
  110.     }
  111.  
  112.     if (rname >= filespec)
  113.         return(rname);
  114.     else
  115.         return(filespec);
  116. }
  117.  
  118. char *parse_path(filespec)
  119.  
  120. char *filespec;
  121.  
  122. {
  123.     static char rbuff[NFILEN];
  124.     char *rname;
  125.  
  126.     /* make a copy we can mung */
  127.     strcpy(rbuff,filespec);
  128.  
  129.     /* starting from the end */
  130.     rname = &rbuff[strlen(rbuff)-1];
  131.  
  132.     /* scan for a directory separator */
  133.     while (rname >= rbuff) {
  134.         if (*rname == DIRSEPCHAR)
  135.             break;
  136.         --rname;
  137.     }
  138.  
  139.     /* no path here! */
  140.     if (rname < rbuff)
  141.         return("");
  142.  
  143.  
  144.     *(rname) = '\0';    /* point just beyond slash */
  145.  
  146.     /* no skip beyond any drive spec */
  147.     rname = rbuff;
  148.     while (*rname) {
  149.         if (*rname == DRIVESEPCHAR)
  150.             return(++rname);
  151.         ++rname;
  152.     }
  153.  
  154.     /* none to be found, return the whole string */
  155.     return(rbuff);
  156. }
  157.  
  158. char *parse_drive(filespec)
  159.  
  160. char *filespec;
  161.  
  162. {
  163.     static char rbuff[NFILEN];
  164.     char *rname;
  165.  
  166.     /* search for a drive specifier */
  167.     strcpy(rbuff,filespec);
  168.     rname = rbuff;
  169.     while (*rname) {
  170.         if (*rname == DRIVESEPCHAR) {
  171.             *(++rname) = 0;
  172.             return(rbuff);
  173.         }
  174.         ++rname;
  175.     }
  176.  
  177.     /* no drive letter/name */
  178.     return("");
  179. }
  180.  
  181. char *dolock(filespec)
  182.  
  183. char *filespec;        /* full file spec of file to lock */
  184.  
  185. {
  186.     struct stat sb;            /* stat buffer for info on files/dirs */
  187.     FILE *fp;            /* ptr to lock file */
  188.     long proc_id;            /* process id from lock file */
  189.     char filename[NFILEN];        /* name of file to lock */
  190.     char pathname[NFILEN];        /* path leading to file to lock */
  191.     char drivename[NFILEN];        /* drive for file to lock */
  192.     char lockpath[NFILEN];        /* lock directory name */
  193.     char lockfile[NFILEN];        /* lock file name */
  194.     char buf[NSTRING];        /* input buffer */
  195.     char host[NSTRING];        /* current host name */
  196.     static char result[NSTRING];    /* error return string */
  197.     char *getenv(); 
  198.  
  199.     /* separate filespec into components */
  200.     strcpy(filename, parse_name(filespec));
  201.     strcpy(pathname, parse_path(filespec));
  202.     strcpy(drivename, parse_drive(filespec));
  203.     if (pathname[0] == 0)
  204.         strcpy(pathname, ".");
  205.  
  206.     /* merge the drive into the pathname */
  207.     strcat(drivename, pathname);
  208.     strcpy(pathname, drivename);
  209.  
  210. #if    LOCKDEBUG
  211.     printf("Locking [%s] [%s]\n", pathname, filename); tgetc();
  212. #endif
  213.  
  214. #if    MSDOS == 0 && WINNT == 0 && OS2 == 0
  215.     /* check to see if we can access the path */
  216.     if (stat(pathname, &sb) != 0) {
  217. #if    LOCKDEBUG
  218.         printf("stat() = %u   errno = %u\n", stat(pathname, &sb), errno); tgetc();
  219. #endif
  220.         strcpy(result, LOCKMSG);
  221.         strcat(result, "Path not found");
  222.         return(result);
  223.     }
  224.     if ((sb.st_mode & S_IFDIR) == 0) {
  225.         strcpy(result, LOCKMSG);
  226.         strcat(result, "Illegal Path");
  227.         return(result);
  228.     }
  229. #endif
  230.  
  231.     /* create the lock directory if it does not exist */
  232.     strcpy(lockpath, pathname);
  233.     strcat(lockpath, DIRSEPSTR);
  234.     strcat(lockpath, LOCKDIR);
  235. #if    LOCKDEBUG
  236.     printf("Lockdir [%s]\n", lockpath); tgetc();
  237. #endif
  238. #if    MSDOS || WINNT || OS2
  239.     if (TRUE) {
  240. #else
  241.     if (stat(lockpath, &sb) != 0) {
  242. #endif
  243.  
  244.         /* create it! */
  245. #if    LOCKDEBUG
  246.         printf("MKDIR(%s)\n", lockpath); tgetc();
  247. #endif
  248. #if    MSDOS || WINNT || OS2
  249.         mkdir(lockpath);
  250. #else
  251.         if (mkdir(lockpath, 0777) != 0) {
  252.             strcpy(result, LOCKMSG);
  253.             switch (errno) {
  254.  
  255.                 case EACCES:
  256.                 strcat(result, "Permission Denied");
  257.                 break;
  258.  
  259.                 case ENOENT:
  260.                 strcat(result, "No such file or directory");
  261.                 break;
  262.             }
  263.             return(result);
  264.         }
  265. #endif
  266.     }
  267.  
  268.     /* check for the existance of this lockfile */
  269.     strcpy(lockfile, lockpath);
  270.     strcat(lockfile, DIRSEPSTR);
  271.     strcat(lockfile, filename);
  272. #if    LOCKDEBUG
  273.     printf("Lockfile [%s]\n", lockfile); tgetc();
  274. #endif
  275.  
  276.     if (stat(lockfile, &sb) != 0) {
  277.  
  278.         /* create the lock file */
  279.         fp = fopen(lockfile, "w");
  280.         if (fp == (FILE *)NULL) {
  281.             strcpy(result, LOCKMSG);
  282.             strcat(result, "Can not open lock file");
  283.             return(result);
  284.         }
  285.  
  286.         /* and output the info needed */
  287. #if    MSDOS || WINNT || OS2
  288.         fprintf(fp, "0\n");        /* process ID */
  289. #endif
  290. #if    SUN
  291.         fprintf(fp, "%u\n", getpid());
  292. #endif
  293.  
  294.         /* user name */
  295.         if (getenv("USER"))
  296.             fprintf(fp, "%s\n", getenv("USER"));
  297.         else
  298.             fprintf(fp, "<unknown>\n");
  299.  
  300.         /* host name */
  301.         if (getenv("HOST"))
  302.             fprintf(fp, "%s\n", getenv("HOST"));
  303.         else {
  304. #if    MSDOS || WINNT || OS2
  305.             fprintf(fp, "<unknown>\n");
  306. #endif
  307. #if    SUN
  308.             gethostname(buf, NFILEN);
  309.             fprintf(fp, "%s\n", buf);
  310. #endif
  311.         }
  312.  
  313.         /* time... */
  314.         fprintf(fp, "%s\n", timeset());
  315.  
  316.         fclose(fp);
  317.         return(NULL);
  318.  
  319.     } else {
  320.  
  321.         /* get the existing lock info */
  322.         fp = fopen(lockfile, "r");
  323.         if (fp == (FILE *)NULL) {
  324.             strcpy(result, LOCKMSG);
  325.             strcat(result, "Can not read lock file");
  326.             return(result);
  327.         }
  328.  
  329.         /* get the process id */
  330.         fgets(buf, NSTRING, fp);
  331.         proc_id = asc_int(buf);
  332.  
  333.         /* get the user name */
  334.         fgets(result, NSTRING, fp);
  335.         result[strlen(result)-1] = 0;
  336.  
  337.         /* get the host name */
  338.         strcat(result, "@");
  339.         fgets(buf, NSTRING, fp);
  340.         buf[strlen(buf)-1] = 0;
  341.         strcat(result, buf);
  342.  
  343. #if    SUN
  344.         /* is it the current host? */
  345.         gethostname(host, NFILEN);
  346.         if (strcmp(buf, host) == 0) {
  347.  
  348.             /* see if the process is dead already */
  349.             if (kill(proc_id, 0) != 0 && errno == ESRCH) {
  350.  
  351.                 /* kill the lock file and retry the lock */
  352.                 fclose(fp);
  353.                 unlink(lockfile);
  354.                 return(dolock(filespec));
  355.             }
  356.         }
  357. #endif
  358.  
  359.         /* get the time */
  360.         strcat(result, " at ");
  361.         fgets(buf, NSTRING, fp);
  362.         buf[strlen(buf)-1] = 0;
  363.         strcat(result, buf);
  364.         fclose(fp);
  365.         return(result);
  366.     }
  367. }
  368.  
  369. /**********************
  370.  *
  371.  * undolock -- unlock the file fname
  372.  *
  373.  * if successful, returns NULL 
  374.  * if other error, returns "LOCK ERROR: explanation"
  375.  *
  376.  *********************/
  377.  
  378. char *undolock(filespec)
  379.  
  380. char *filespec;        /* filespec to unlock */
  381.  
  382. {
  383.     char filename[NFILEN];        /* name of file to lock */
  384.     char pathname[NFILEN];        /* path leading to file to lock */
  385.     char drivename[NFILEN];        /* drive for file to lock */
  386.     char lockpath[NFILEN];        /* lock directory name */
  387.     char lockfile[NFILEN];        /* lock file name */
  388.     static char result[NSTRING];    /* error return string */
  389.  
  390.     /* separate filespec into components */
  391.     strcpy(filename, parse_name(filespec));
  392.     strcpy(pathname, parse_path(filespec));
  393.     strcpy(drivename, parse_drive(filespec));
  394.     if (pathname[0] == 0)
  395.         strcpy(pathname, ".");
  396.  
  397.     /* merge the drive into the pathname */
  398.     strcat(drivename, pathname);
  399.     strcpy(pathname, drivename);
  400.  
  401. #if    LOCKDEBUG
  402.     printf("\nUnLocking [%s] [%s]\n", pathname, filename); tgetc();
  403. #endif
  404.  
  405.     /* create the lock directory if it does not exist */
  406.     strcpy(lockpath, pathname);
  407.     strcat(lockpath, DIRSEPSTR);
  408.     strcat(lockpath, LOCKDIR);
  409. #if    LOCKDEBUG
  410.     printf("Lockdir [%s]\n", lockpath); tgetc();
  411. #endif
  412.     /* check for the existance of this lockfile */
  413.     strcpy(lockfile, lockpath);
  414.     strcat(lockfile, DIRSEPSTR);
  415.     strcat(lockfile, filename);
  416. #if    LOCKDEBUG
  417.     printf("Lockfile [%s]\n", lockfile); tgetc();
  418. #endif
  419.     if (unlink(lockfile)) { 
  420.         strcat(result, "could not remove lock file"); 
  421.         return(result); 
  422.     } else {
  423.         rmdir(lockpath);   /* this will work only if dir is empty */
  424.             return(NULL);
  425.     }
  426. }
  427.  
  428. #else
  429. dolhello()
  430. {
  431. }
  432. #endif
  433.  
  434.